/**
 * 
 */
package cn.ivicar.message.push.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Inject;

import cn.com.carsmart.ws.model.AppPush;
import cn.com.carsmart.ws.model.PushCustomerClient;
import cn.ivicar.message.push.service.AppPushService;
import cn.ivicar.message.push.service.NotificationService;
import cn.ivicar.message.push.util.MesagePushProperties;
import cn.jiguang.common.ClientConfig;
import cn.jiguang.common.ServiceHelper;
import cn.jiguang.common.connection.ApacheHttpClient;
import cn.jiguang.common.connection.NettyHttpClient;
import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;
import net.sf.json.JSONObject;

/**
 * @author liurunbin 2017年5月23日 cn.ivicar.message.push.controller
 */
public class PushController {

	private static transient final Logger LOGGER = LoggerFactory.getLogger(PushController.class);

	public static ExecutorService threadPool = Executors.newFixedThreadPool(10);

	protected static final String APP_KEY = "b61859c47d52e438b715f81a";
	protected static final String MASTER_SECRET = "6835bde8aa5ce87e530bccdc";

	@Inject
	private NotificationService notificationService;
	@Inject
	private AppPushService appPushService;

	/**
	 * {"customerId":"540","category":"shake","vehicleSerial":"71389d4e3169918","vehicleName":"汉兰达","time":"2017-05-24 17:22:55","licensePlate":"琼BZ7883"}
	 * category : voltage/shake  车辆电压过低/车辆发生振动
	 */
	public void process(final JSONObject params) {
		threadPool.execute(new Runnable() {

			@Override
			public void run() {
				try {
					
					sendPush(params);
				} catch (Exception e) {
					LOGGER.info("推送消息内容:"+params.toString());
					LOGGER.error("推送消息失败",e);
				}
			}
		});
	}
    /*
    验证信息并发送信息
     */
	public void sendPush(JSONObject params) {
		
		if(params == null || params.isEmpty()){
			LOGGER.warn("推送协议为空,停止推送");
			return;
		}

		Long customerId = params.optLong("user_id");
		if (customerId == null || customerId.intValue() <= 0) {
			LOGGER.warn(String.format("推送协议没有指定用户,停止推送", customerId));
			return;
		}
		List<PushCustomerClient> list = notificationService.get(customerId);
		if (list == null || list.isEmpty()) {
			LOGGER.warn(String.format("用户[customerId=%s]暂无可用的clientId,停止推送", customerId));
			return;
		}

		for (PushCustomerClient client : list) {
			sendPushPayload(params, client);
		}

	}
    /*
    验证接收者并发送信息
     */
	private void sendPushPayload(JSONObject params, PushCustomerClient client) {

		if (client == null || client.getAppId() == null) {
			LOGGER.warn(String.format("用户[customerId=%s]没有关联推送应用,停止推送", params.optString("customerId")));
			return;
		}

		AppPush appPush = appPushService.get(client.getAppId());

		if (appPush == null) {
			LOGGER.warn(String.format("推送应用[appPushId=%s]不存在,停止推送", client.getAppId()));
			return;
		}

		ClientConfig clientConfig = ClientConfig.getInstance();
		clientConfig.setMaxRetryTimes(5);
		clientConfig.setConnectionRequestTimeout(5000);
		clientConfig.setReadTimeout(5000);
		clientConfig.setSocketTimeout(5000);
		final JPushClient jpushClient = new JPushClient(appPush.getMasterSecret(), appPush.getAppKey(), null,
				clientConfig);
		String authCode = ServiceHelper.getBasicAuthorization(appPush.getAppKey(), appPush.getMasterSecret());
		//NettyHttpClient httpClient = new NettyHttpClient(authCode, null, clientConfig);
		ApacheHttpClient httpClient = new ApacheHttpClient(authCode, null, clientConfig);
		//NettyHttpClient httpClient = new NettyHttpClient(authCode, null, clientConfig)
		jpushClient.getPushClient().setHttpClient(httpClient);
		
		
		
		final PushPayload payload = buildPushPayload(params, client.getClientId());

		long start = System.currentTimeMillis();

		try {
			PushResult result = jpushClient.sendPush(payload);
			LOGGER.info("Got result - " + result);

		} catch (APIConnectionException e) {
			LOGGER.error("Connection error. Should retry later. ", e);
			LOGGER.error("Sendno: " + payload.getSendno());

		} catch (APIRequestException e) {
			LOGGER.error("Error response from JPush server. Should review and fix it. ", e);
			LOGGER.info("HTTP Status: " + e.getStatus());
			LOGGER.info("Error Code: " + e.getErrorCode());
			LOGGER.info("Error Message: " + e.getErrorMessage());
			LOGGER.info("Msg ID: " + e.getMsgId());
			LOGGER.error("Sendno: " + payload.getSendno());
		}
		long end = System.currentTimeMillis();
		LOGGER.warn(String.format("推送结束%s耗时[%s]毫秒", payload.toString(),(end - start)));
	}
    /*
    创建极光推送中的pushpayload
     */
	private PushPayload buildPushPayload(JSONObject params, String clientId) {
		Map<String, String> extras = new HashMap<String, String>();
		
		extras.put("user_id", params.optString("user_id", ""));
		extras.put("car_serial", params.optString("car_serial", ""));
		extras.put("real_message", params.optString("real_message", ""));
		extras.put("car_name", params.optString("car_name", ""));
		extras.put("time", params.optString("time", ""));
		extras.put("from", params.optString("from", ""));
		extras.put("message", params.optString("message", ""));
		extras.put("car_license", params.optString("car_license", ""));
		String alert = params.optString("alert", "");
		
		Notification notification = Notification.newBuilder()
				.setAlert("")
				.addPlatformNotification(
						AndroidNotification.newBuilder()
						.setAlert(alert)
						.setTitle("")
						.addExtras(extras)
						.build())
				.addPlatformNotification(
						IosNotification.newBuilder()
						.setAlert(alert)
						.setSound("a.caf")
						.incrBadge(1)
						.addExtras(extras)
						.build())
				.build();
		return PushPayload.newBuilder()
				.setPlatform(Platform.all())
				.setAudience(Audience.registrationId(clientId))
				.setNotification(notification)
				.setOptions(Options.newBuilder()
						.setTimeToLive(86400)
						.setApnsProduction(params.optBoolean("apns",MesagePushProperties.getApnsProduction()))
						.build())
				.build();
	}
}
